home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2004 May / SGI IRIX 6.5 Applications 2004 May.iso / dist / java3d.idb / usr / demos / java / j3d / programs / examples / VirtualInputDevice / WheelControls.java.z / WheelControls.java
Encoding:
Java Source  |  2003-08-08  |  10.5 KB  |  395 lines

  1. /*
  2.  *    @(#)WheelControls.java 1.9 02/04/01 15:03:54
  3.  *
  4.  * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  *
  13.  * - Redistribution in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in
  15.  *   the documentation and/or other materials provided with the
  16.  *   distribution.
  17.  *
  18.  * Neither the name of Sun Microsystems, Inc. or the names of
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  *
  22.  * This software is provided "AS IS," without a warranty of any
  23.  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
  24.  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
  26.  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
  27.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  28.  * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
  29.  * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
  30.  * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  31.  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  32.  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
  33.  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  34.  *
  35.  * You acknowledge that Software is not designed,licensed or intended
  36.  * for use in the design, construction, operation or maintenance of
  37.  * any nuclear facility.
  38.  */
  39.  
  40. import java.awt.*;
  41. import java.awt.geom.*;
  42. import java.awt.event.*;
  43.  
  44. public class WheelControls extends Canvas implements RotationControls, MouseMotionListener, MouseListener {
  45.  
  46.     private final static int NONE=0;
  47.     private final static int SLIDE_Y=1;
  48.     private final static int SLIDE_X=2;
  49.     private final static int SLIDE_Z=3;
  50.  
  51.     private int mode = NONE;
  52.  
  53.     private Dimension size;
  54.     private int thickness;
  55.     private int diameter;
  56.     private int space;
  57.     private int pipSize;
  58.     private int pipOffset;    // Amount pip is below wheel
  59.     private int margin;        // Margin between edge of Canvas and
  60.                 // controls
  61.  
  62.     private Polygon yPip;
  63.     private Rectangle yBackClip;
  64.  
  65.     private Polygon xPip;
  66.     private Rectangle xBackClip;
  67.  
  68.     private Polygon zPip;
  69.  
  70.     private Rectangle yArea;
  71.     private Rectangle xArea;
  72.     private Rectangle zArea;
  73.  
  74.     private Point oldMousePos = new Point();
  75.  
  76.     float yAngle = 0.0f;
  77.     float xAngle = 0.0f;
  78.     float zAngle = 0.0f;
  79.  
  80.     float yOrigAngle;
  81.     float xOrigAngle;
  82.     float zOrigAngle;
  83.  
  84.     float angleStep = (float)Math.PI/30.0f;
  85.  
  86.     public WheelControls() {
  87.     this(0.0f, 0.0f, 0.0f);
  88.     }
  89.  
  90.     public WheelControls( float rotX, float rotY, float rotZ ) {
  91.     size = new Dimension( 200, 200 );
  92.  
  93.     xAngle = constrainAngle(rotX);
  94.     yAngle = constrainAngle(rotY);
  95.     zAngle = constrainAngle(rotZ);
  96.  
  97.         yOrigAngle = yAngle;
  98.         xOrigAngle = xAngle;
  99.         zOrigAngle = zAngle;
  100.  
  101.     setSizes();
  102.  
  103.     yPip = new Polygon();
  104.     yPip.addPoint( 0, 0 );
  105.     yPip.addPoint( -pipSize/2, pipSize );
  106.     yPip.addPoint( pipSize/2, pipSize );
  107.  
  108.     xPip = new Polygon();
  109.     xPip.addPoint(0,0);
  110.     xPip.addPoint( pipSize, -pipSize/2 );
  111.     xPip.addPoint( pipSize, pipSize/2 );
  112.  
  113.     zPip = new Polygon();
  114.     zPip.addPoint( diameter/2, pipOffset );
  115.     zPip.addPoint( diameter/2-pipSize/2, pipOffset-pipSize );
  116.     zPip.addPoint( diameter/2+pipSize/2, pipOffset-pipSize );
  117.  
  118.     addMouseListener( this );
  119.     addMouseMotionListener( this );
  120.     }
  121.  
  122.     private void setSizes() {
  123.     margin = 10;
  124.     int width = size.width - margin*2;
  125.     thickness = width * 7 / 100;
  126.     diameter = width * 70 / 100;
  127.     space = width * 10 / 100;
  128.     pipSize = width * 7 / 100;
  129.  
  130.     pipOffset = thickness/2;
  131.  
  132.     }
  133.  
  134.     public void paint( Graphics g ) {
  135.     Graphics2D g2 = (Graphics2D)g;
  136.  
  137.     g.drawOval( margin,margin, diameter, diameter );
  138.     zArea = new Rectangle( margin, margin, diameter, diameter );
  139.     drawZPip( g2, zAngle );
  140.  
  141.     g.drawRect( margin, margin+diameter+space, 
  142.             diameter, thickness ); // Y Wheel
  143.     yArea = new Rectangle( margin, margin+diameter+space, margin+diameter, 
  144.                    thickness+pipOffset );
  145.     yBackClip = new Rectangle( margin-thickness, 
  146.                    margin+diameter+space+thickness, 
  147.                    margin+diameter+thickness*2, thickness );
  148.     drawYPip( g2, yAngle );
  149.  
  150.     g.drawRect( margin+diameter+space, margin, 
  151.             thickness, diameter ); // X Wheel
  152.     xArea = new Rectangle( margin+diameter+space, margin, 
  153.                    thickness+pipOffset, margin+diameter );
  154.     xBackClip = new Rectangle( margin+diameter+space+thickness, 
  155.                    margin-thickness, 
  156.                    thickness, margin+diameter+thickness*2 );
  157.     drawXPip( g2, xAngle );
  158.  
  159.  
  160.     }
  161.  
  162.     public float getXAngle() {
  163.     return xAngle;
  164.     }
  165.  
  166.     public float getYAngle() {
  167.     return yAngle;
  168.     }
  169.  
  170.     public float getZAngle() {
  171.     return zAngle;
  172.     }
  173.  
  174.  
  175.     public void reset() {
  176.                 // Overwrite the old pip
  177.                 drawYPip( (Graphics2D)(this.getGraphics()),
  178.                           yAngle );
  179.                 yAngle = yOrigAngle;
  180.                 // Draw the new Pip
  181.                 drawYPip( (Graphics2D)(this.getGraphics()),
  182.                           yAngle );
  183.  
  184.                 // Overwrite the old pip
  185.                 drawXPip( (Graphics2D)(this.getGraphics()),
  186.                           xAngle );
  187.                 xAngle = xOrigAngle;
  188.                 // Draw the new Pip
  189.                 drawXPip( (Graphics2D)(this.getGraphics()),
  190.                           xAngle );
  191.  
  192.                 drawZPip( (Graphics2D)(this.getGraphics()),
  193.                           zAngle );
  194.  
  195.                 zAngle =  zOrigAngle;
  196.  
  197.                 drawZPip( (Graphics2D)(this.getGraphics()),
  198.                           zAngle );
  199.                 oldMousePos.setLocation(0,0);
  200.     }
  201.  
  202.  
  203.     private void drawXPip( Graphics2D g2, float angle ) {
  204.     AffineTransform trans = new AffineTransform();
  205.     int y;
  206.     int xOrig = margin+diameter+space;
  207.     int yOrig = margin;
  208.     Color origColor = g2.getColor();
  209.  
  210.     if (angle <= Math.PI) {
  211.         y = yOrig + diameter - (int)((Math.abs( angle-Math.PI/2 )/(Math.PI/2)) * diameter/2);
  212.     } else
  213.         y = yOrig + (int)((Math.abs( (angle-Math.PI*1.5) )/(Math.PI/2)) * diameter/2);
  214.  
  215.     if (angle<Math.PI/2 || angle > Math.PI*1.5)
  216.         g2.setColor( Color.red );        // Infront of wheel
  217.     else {
  218.         g2.setColor( Color.black );        // Behind Wheel
  219.         g2.setClip( xBackClip );
  220.     }
  221.  
  222.     g2.setXORMode( getBackground() );
  223.     trans.setToTranslation( xOrig+pipOffset, y );
  224.     g2.setTransform( trans );
  225.     g2.fillPolygon( xPip );
  226.  
  227.     // Reset graphics context
  228.     trans.setToIdentity();
  229.     g2.setTransform( trans );
  230.     g2.setColor(origColor);
  231.     g2.setPaintMode();
  232.     }
  233.  
  234.     private void drawYPip( Graphics2D g2, float angle ) {
  235.     AffineTransform trans = new AffineTransform();
  236.     int x;
  237.     int xOrig = margin;
  238.     int yOrig = margin+diameter+space;
  239.     Color origColor = g2.getColor();
  240.  
  241.     if (angle <= Math.PI) {
  242.         x = xOrig + diameter - (int)((Math.abs( angle-Math.PI/2 )/(Math.PI/2)) * diameter/2);
  243.     } else
  244.         x = xOrig + (int)((Math.abs( (angle-Math.PI*1.5) )/(Math.PI/2)) * diameter/2);
  245.  
  246.     if (angle<Math.PI/2 || angle > Math.PI*1.5)
  247.         g2.setColor( Color.red );        // Infront on wheel
  248.     else {
  249.         g2.setColor( Color.black );        // Behind Wheel
  250.         g2.setClip( yBackClip );
  251.     }
  252.  
  253.     g2.setXORMode( getBackground() );
  254.     trans.setToTranslation( x, yOrig+pipOffset );
  255.     g2.setTransform( trans );
  256.     g2.fillPolygon( yPip );
  257.  
  258.     // Reset graphics context
  259.     trans.setToIdentity();
  260.     g2.setTransform( trans );
  261.     g2.setColor(origColor);
  262.     g2.setPaintMode();
  263.     }
  264.  
  265.     private void drawZPip( Graphics2D g2, float zAngle ) {
  266.     AffineTransform trans = new AffineTransform();
  267.     Color origColor = g2.getColor();
  268.  
  269.     trans.translate( margin, margin );
  270.     trans.rotate(zAngle, diameter/2, diameter/2 );
  271.  
  272.     g2.setXORMode( getBackground() );
  273.     g2.setTransform(trans);
  274.     g2.setColor( Color.red );
  275.     g2.fillPolygon( zPip );
  276.  
  277.     // Reset graphics context
  278.     trans.setToIdentity();
  279.     g2.setTransform( trans );
  280.     g2.setColor( origColor );
  281.     g2.setPaintMode();
  282.     }
  283.  
  284.     public Dimension getPreferredSize() {
  285.     return size;
  286.     }
  287.  
  288.     public void setSize( Dimension d ) {
  289.     // Set size to smallest dimension
  290.     if (d.width<d.height)
  291.         size.width = size.height = d.width;
  292.     else
  293.         size.width = size.height = d.height;
  294.     setSizes();
  295.     }
  296.  
  297.     public void mouseClicked( MouseEvent e ) {
  298.     }
  299.  
  300.     public void mouseEntered( MouseEvent e ) {
  301.     }
  302.  
  303.     public void mouseExited( MouseEvent e ) {
  304.     }
  305.  
  306.     public void mousePressed( MouseEvent e ) {
  307.     if ( yArea.contains( e.getPoint() )) {
  308.         mode = SLIDE_Y;
  309.         oldMousePos = e.getPoint();
  310.     } else if (xArea.contains( e.getPoint() )) {
  311.         mode = SLIDE_X;
  312.         oldMousePos = e.getPoint();
  313.     } else if (zArea.contains( e.getPoint() )) {
  314.         mode = SLIDE_Z;
  315.         oldMousePos = e.getPoint();
  316.     }
  317.     }
  318.  
  319.     public void mouseReleased( MouseEvent e ) {
  320.     mode = NONE;
  321.     }
  322.  
  323.     public void mouseDragged( MouseEvent e ) {
  324.     Point pos = e.getPoint();
  325.  
  326.     int diffX = pos.x - oldMousePos.x;
  327.     int diffY = pos.y - oldMousePos.y;
  328.  
  329.     switch(mode) {
  330.         case NONE:
  331.         break;
  332.         case SLIDE_Y:
  333.         // Overwrite the old pip
  334.         drawYPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
  335.               yAngle );
  336.         if (diffX<0)
  337.             yAngle -= angleStep;
  338.         else if (diffX>0)
  339.             yAngle += angleStep;
  340.  
  341.         yAngle = constrainAngle(yAngle);
  342.  
  343.         // Draw the new Pip
  344.         drawYPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
  345.               yAngle );
  346.             oldMousePos = pos;
  347.         break;
  348.         case SLIDE_X:
  349.         // Overwrite the old pip
  350.         drawXPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
  351.               xAngle );
  352.         if (diffY<0)
  353.             xAngle -= angleStep;
  354.         else if (diffY>0)
  355.             xAngle += angleStep;
  356.  
  357.         xAngle = constrainAngle(xAngle);
  358.  
  359.         // Draw the new Pip
  360.         drawXPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
  361.               xAngle );
  362.             oldMousePos = pos;
  363.         break;
  364.         case SLIDE_Z:
  365.         drawZPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
  366.               zAngle );
  367.  
  368.         if (diffX<0)
  369.             zAngle -= angleStep;
  370.         else if (diffX>0)
  371.             zAngle += angleStep;
  372.  
  373.         zAngle = constrainAngle( zAngle );
  374.         drawZPip( (Graphics2D)((Canvas)e.getSource()).getGraphics(),
  375.               zAngle );
  376.             oldMousePos = pos;
  377.         break;
  378.         default:
  379.         throw( new RuntimeException("Internal Error"));
  380.     }
  381.     }
  382.  
  383.     public void mouseMoved( MouseEvent e ) {
  384.     }
  385.  
  386.     /**
  387.       * Constrain angle to be 0<angle<2PI
  388.       */
  389.     private float constrainAngle( float angle ) {
  390.         if ( angle > (float)Math.PI*2 ) return angle-(float)Math.PI*2;
  391.         if ( angle < 0.0f) return angle+(float)Math.PI*2;
  392.     return angle;
  393.     }
  394. }
  395.